package com.xframe.xdal.core.model.mapping;

import com.xframe.xdal.core.annotation.*;
import com.xframe.xdal.core.constant.*;
import com.xframe.xdal.core.exception.DalFrameException;
import com.xframe.xdal.core.util.XReflect;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 构建对象映射表
 *
 * @author xufeng
 * @version 1.0
 * @date 2022-09-19
 */
public class TableInfoBuilder {

    /**
     * 根据对象的注解来构造数据表的结构对象
     * @param dataType 数据类型
     *
     * @return ITableInfo的实现对象
     */
    public static ITableInfo BuildTableInfoByAnnotation(Class<?> dataType) {
        if(dataType == null){
            throw new DalFrameException(ErrorCode.CLASS_TYPE_NULL, ErrorMsg.CLASS_TYPE_NULL_MSG);
        }
        XTable[] xTables = dataType.getAnnotationsByType(XTable.class);
        if (xTables.length == 0) {
            throw new DalFrameException(ErrorCode.NOT_FIND_TABLEINFO, ErrorMsg.TABLEINFO_NO_FIND_MSG);
        }
        XTable xTable = xTables[0];
        TableInfo tableInfo = new TableInfo(xTable.value(),dataType.getName(), dataType.getSimpleName(),xTable.label(),xTable.indexName(),xTable.dataSourceCode());
        ArrayList<IColumnMapping> columnMappingList = new ArrayList<>();
        ArrayList<IColumnMapping> pkColumnMappingList = new ArrayList<>();
        Field[] fields = XReflect.getFields(dataType);
        for(Field field:fields){
            XColumn[] columns = field.getAnnotationsByType(XColumn.class);
            if(columns.length > 0) {
                ColumnMapping columnMapping = ColumnMapping.valueOf(columns[0], field);
                if (columnMapping.getPrimaryKeyFlag()) {
                    pkColumnMappingList.add(columnMapping);
                } else {
                    columnMappingList.add(columnMapping);
                }
            }
        }
        pkColumnMappingList.addAll(columnMappingList);
        tableInfo.setColumnMappingList(pkColumnMappingList);
        columnMappingList.clear();
        // 检查引用列
        XBelongsTo[] xBelongsTos = dataType.getAnnotationsByType(XBelongsTo.class);
        for(XBelongsTo xBelongsTo:xBelongsTos){
            tableInfo.getBelongsToMappingList().add(BelongsToMapping.valueOf(xBelongsTo));
        }
        // 检查子列的引用关系
        XHasMany[] xHasManys = dataType.getAnnotationsByType(XHasMany.class);
        for(XHasMany xHasMany:xHasManys){
            tableInfo.getHasManyMappingList().add(HasManyMapping.valueOf(xHasMany));
        }
        if(tableInfo.getColumnMappingList() == null || tableInfo.getColumnMappingList().size() == 0){
            throw new DalFrameException(ErrorCode.COLUMNMAPPING_NOT_FIND, ErrorMsg.COLUMNMAPPING_NOT_FIND_MSG);
        }
        return tableInfo;
    }


    public static XSelectItemCollect findXSelectItem(Class<?> dataType){
        if(dataType == null){
            throw new DalFrameException(ErrorCode.CLASS_TYPE_NULL, ErrorMsg.CLASS_TYPE_NULL_MSG);
        }
        XSelectItem[] XSelectItems = dataType.getAnnotationsByType(XSelectItem.class);
        Map<String,XSelectItemModel> selectItemModelMap = new HashMap<>();
        if(XSelectItems != null) {
            for (XSelectItem selectItem : XSelectItems) {
                XSelectItemModel xSelectItemModel = new XSelectItemModel();
                xSelectItemModel.setCodeName(selectItem.codeName());
                xSelectItemModel.setLanguage(selectItem.language());
                xSelectItemModel.setKeyName(selectItem.keyName());
                xSelectItemModel.setTextName(selectItem.textName());
                selectItemModelMap.put(xSelectItemModel.getLanguage(),xSelectItemModel);
            }
        }
        return new XSelectItemCollect(selectItemModelMap);
    }
}
